package com.example.pixelyear.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.os.Handler
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import com.example.pixelyear.Interface.OnPixelClickListener
import com.example.pixelyear.R
import com.example.pixelyear.bean.DateBean
import com.example.pixelyear.bean.IntStringBooleanBean
import com.example.pixelyear.utils.UIUtils
import com.example.pixelyear.utils.Utils
import com.socks.library.KLog
import kotlin.math.abs

class PixelView @JvmOverloads constructor(
    context: Context,
    attributes: AttributeSet? = null,
    defaultStyle: Int = 0
) :
    View(context, attributes, defaultStyle) {

    private var boxWidth = UIUtils.getDimension(R.dimen.dp_50) //宽度
    private var boxHeight = UIUtils.getDimension(R.dimen.dp_50) //高度
    private val boxPadding = 3 //分割线宽度
    private var columnSize = 0//行数
    private var rowSize = 7 //列数

    private var lastColor = Color.WHITE
    private var days = 0
    private var week = 0//星期 用来判断每月一次需要空几格
    private var dimen10 = UIUtils.getDimensionFloat(R.dimen.dp_10) //圆距离边的距离
    private var dimen5 = UIUtils.getDimensionFloat(R.dimen.dp_5) //远的半径
    private var month = 0//需要画的月份
    private var year = 0 //需要画的年份
    private var nowMonth = 0    //现在年份
    private var nowYear = 0  //现在月份
    private var nowDay = 0  //现在日期 天

    private var nowDayWidth = 0 //今 字的宽度
    private var nowDayHeight = 0 //今 字的高度
    private var moodTextWidth = 0 //表情文字宽度
    private val paint = UIUtils.getString(R.string.paint)

    private lateinit var checkForLongPress: CheckForLongPress
    private lateinit var checkForClickPress: CheckForClickPress

    private val dateList = mutableListOf<DateBean>()

    private var onPixelClickListener: OnPixelClickListener? = null

    private val mHandler by lazy {
        Handler()
    }

    //正常日期画笔
    private val boxPaint by lazy {
        Paint().also {
            it.color = Color.WHITE
            it.flags = Paint.ANTI_ALIAS_FLAG
        }
    }

    //空白日期画笔
    private val emptyPaint by lazy {
        Paint().also {
            it.color = UIUtils.getColor(R.color.black_F7F7F7)
            it.flags = Paint.ANTI_ALIAS_FLAG
        }
    }


    //日期文字画笔
    private val textDayPaint by lazy {
        Paint().also {
            it.color = UIUtils.getColor(R.color.black_999999)
            it.flags = Paint.ANTI_ALIAS_FLAG
            it.textSize = UIUtils.getDimensionFloat(R.dimen.sp_15)
        }
    }

    //今天任务标记
    private val nowDayPaint by lazy {
        Paint().also {
            it.color = UIUtils.getColor(R.color.black_999999)
            it.flags = Paint.ANTI_ALIAS_FLAG
            it.textSize = UIUtils.getDimensionFloat(R.dimen.sp_7)
        }
    }

    //今天任务标记
    private val moodPaint by lazy {
        Paint().also {
            it.color = UIUtils.getColor(R.color.black_999999)
            it.flags = Paint.ANTI_ALIAS_FLAG
            it.typeface = UIUtils.getTextFont(context)
            it.textSize = UIUtils.getDimensionFloat(R.dimen.sp_12)
        }
    }

    private val dayRect by lazy {
        Rect()
    }

    private val nowDayRect by lazy {
        Rect()
    }

    private val moodRect by lazy {
        Rect()
    }

    init {
        initTextWidth()
        initTime()
    }

    private fun initTextWidth() {

        nowDayPaint.getTextBounds("今", 0, "今".length, nowDayRect)
        //计算今字的上左间距
        nowDayHeight = (nowDayRect.height() * 1.5).toInt()
        nowDayWidth = nowDayRect.width()

        moodPaint.getTextBounds(paint, 0, paint.length, moodRect)
        moodTextWidth = moodRect.width()
    }

    private fun initTime() {
        if (month == 0 || year == 0) return
        nowMonth = Utils.getMonth()
        nowYear = Utils.getYear()
        nowDay = Utils.getDay()
        week = Utils.dateTranslateWeek("$year-$month-01") - 1
        days = month.let {
            if (it == 1 || it == 3 || it == 5 || it == 7 || it == 8 || it == 10 || it == 12) {
                31
            } else if (it == 2) {
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    29
                } else 28
            } else {
                30
            }
        }
        columnSize = if ((days + week) % 7 == 0) (days + week) / 7 else (days + week) / 7 + 1
//        KLog.e("yxs", "计算的多少行：$year 年$month 月 行数$columnSize ===$week ===天数$days")
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        var w = 0
        var h = 0

        if (widthMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
            w = boxWidth * rowSize + boxPadding
        }

        if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
            //加一是加上星期行的高度
            h = boxHeight * (columnSize) + boxPadding
        }
//        KLog.e("yxs", "高度宽度：" + w + "===" + h + " ===月份$month")
        setMeasuredDimension(w, h)
    }

    override fun onDraw(canvas: Canvas?) {
        for (i in 0 until columnSize) {
            for (j in 0 until rowSize) {

                val thisDay = (i * rowSize) + j + 1
                if (thisDay - week <= days && thisDay > week) {
                    val filter = dateList.filter { it.day == (thisDay - week) }
                    if (filter.isNotEmpty()) {
                        if (lastColor != filter[0].color) {
                            lastColor = filter[0].color
                            boxPaint.color = lastColor
                            textDayPaint.color = filter[0].textColor
                            nowDayPaint.color = filter[0].textColor
                            moodPaint.color = filter[0].textColor
                        }
                        //画有标记的日期
                        canvas?.drawRect(
                            (boxWidth * j).toFloat() + boxPadding,
                            (boxHeight * i).toFloat() + boxPadding,
                            ((boxWidth) * (j + 1)).toFloat(),
                            ((boxHeight) * (i + 1)).toFloat(), boxPaint
                        )

                        //画心情
                        canvas?.drawText(
                            filter[0].mood,
                            (boxWidth * j).toFloat() + boxPadding + (boxWidth - moodTextWidth) / 2,
                            ((boxHeight) * (i + 1)).toFloat() - dimen5,
                            moodPaint
                        )

                        //画有任务标记
                        if (filter[0].note.isNotEmpty()) {
                            canvas?.drawText(
                                paint,
                                ((boxWidth) * (j + 1)).toFloat() - dimen10 - dimen5,
                                ((boxHeight) * (i + 1)).toFloat() - dimen5,
                                moodPaint
                            )
                        }
                    } else {
                        if (lastColor != Color.WHITE) {
                            lastColor = Color.WHITE
                            boxPaint.color = lastColor

                            textDayPaint.color = UIUtils.getColor(R.color.black_999999)
                            nowDayPaint.color = UIUtils.getColor(R.color.black_999999)
                        }
                        //画没有记录的日期
                        canvas?.drawRect(
                            (boxWidth * j).toFloat() + boxPadding,
                            (boxHeight * i).toFloat() + boxPadding,
                            ((boxWidth) * (j + 1)).toFloat(),
                            ((boxHeight) * (i + 1)).toFloat(), boxPaint
                        )
                    }

                    //画日期文字
                    with((thisDay - week).toString()) {
                        textDayPaint.getTextBounds(this, 0, length, dayRect)

                        canvas?.drawText(
                            this,
                            (boxWidth * j).toFloat() + boxPadding + getTextRightPadding(),
                            ((boxHeight) * (i + 1)).toFloat() - getTextTopPadding(), textDayPaint
                        )
                    }

                } else {
                    //画没有字的块
                    canvas?.drawRect(
                        (boxWidth * j).toFloat() + boxPadding,
                        (boxHeight * i).toFloat() + boxPadding,
                        ((boxWidth) * (j + 1)).toFloat(),
                        ((boxHeight) * (i + 1)).toFloat(), emptyPaint
                    )
                }

                if (year == nowYear && month == nowMonth && (thisDay - week) == nowDay) {
                    KLog.e("yxs", "日期：$thisDay===$nowDay===$j====$i")
                    canvas?.drawText(
                        "今",
                        (boxWidth * j).toFloat() + boxPadding + nowDayWidth,
                        ((boxHeight) * (i)).toFloat() + nowDayHeight,
                        nowDayPaint
                    )
                }

            }
        }

    }

    private var onLongTouch = false
    private var downX: Float = 0f
    private var downY: Float = 0f
    override fun onTouchEvent(event: MotionEvent): Boolean {
        val x = event.x
        val y = event.y
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.x
                downY = event.y
                removeLongPress()
                postLongPress(ViewConfiguration.getLongPressTimeout().toLong(), x, y)
            }
            MotionEvent.ACTION_MOVE -> {
                if (abs(x - downX) > 10 || abs(y - downY) > 10) {
                    removeLongPress()
                    return true
                } else {
                    if (hasPendingLongPressCallback()) {
                        removeLongPress()
                        var delay = ViewConfiguration.getLongPressTimeout().toLong()
                        delay -= event.eventTime - event.downTime
                        postLongPress(delay, x, y)
                    }
                }
            }
            MotionEvent.ACTION_UP -> {
                downX = 0f
                downY = 0f
                if (onLongTouch) return true
                removeLongPress()
                postClickPress(x, y)
            }
            else -> {

            }
        }
        return true
    }

    private fun getTextTopPadding(): Float {
        return ((boxHeight - dayRect.height()) / 2).toFloat()
    }

    private fun getTextRightPadding(): Float {
        return ((boxWidth - dayRect.width()) / 2).toFloat()

    }

    fun updateMonthAndYear(month: Int, year: Int) {
        this.month = month
        this.year = year
        initTime()
        requestLayout()
    }


    fun updateDateList(list: MutableList<DateBean>) {
        dateList.clear()
        dateList.addAll(list)
        invalidate()
    }

    //获取点击日期的数据
    private fun getNowDayData(thisDay: Int): IntStringBooleanBean {
        return if (dateList.isNotEmpty()) {
            dateList.filter { it.day == thisDay }.let {
                if (it.isNullOrEmpty())
                    IntStringBooleanBean(-1, "", false)
                else IntStringBooleanBean(it[0].color, it[0].mood, it[0].note.isNotEmpty())
            }
        } else IntStringBooleanBean(-1, "", false)
    }

    fun setOnPixelClickListener(onPixelClickListener: OnPixelClickListener) {
        this.onPixelClickListener = onPixelClickListener
    }

    //添加长按任务
    private fun postLongPress(delay: Long, x: Float, y: Float) {
        if (!this::checkForLongPress.isInitialized)
            checkForLongPress = CheckForLongPress()
        onLongTouch = false
        checkForLongPress.setXY(x, y)
        mHandler.postDelayed(checkForLongPress, delay)
    }

    //单击任务
    private fun postClickPress(x: Float, y: Float) {
        if (!this::checkForClickPress.isInitialized)
            checkForClickPress = CheckForClickPress()
        onLongTouch = false
        checkForClickPress.setXY(x, y)
        mHandler.post(checkForClickPress)
    }

    //移除长按任务
    private fun removeLongPress() {
        if (this::checkForLongPress.isInitialized)
            mHandler.removeCallbacks(checkForLongPress)
    }

    //判断是否有长按任务
    private fun hasPendingLongPressCallback(): Boolean {
        return if (!this::checkForLongPress.isInitialized)
            false
        else
            mHandler.hasCallbacks(checkForLongPress)
    }


    //长按内部类
    private inner class CheckForLongPress : Runnable {
        private var mX: Float = 0.toFloat()
        private var mY: Float = 0.toFloat()

        override fun run() {
            val w = mX.div(boxWidth).toInt()
            val h = mY.div(boxHeight).toInt()
            val clickDay = (h) * 7 + w + 1 - week
            val bean = getNowDayData(clickDay)
            if ((bean.boolean || bean.str.isNotEmpty())) {//长按
                onLongTouch = true
                onPixelClickListener?.OnLongClick(
                    year,
                    month,
                    clickDay,
                    bean.int,
                    bean.boolean,
                    bean.str
                )
            }
        }

        fun setXY(x: Float, y: Float) {
            mX = x
            mY = y
        }
    }

    //单机内部类
    private inner class CheckForClickPress : Runnable {
        private var mX: Float = 0.toFloat()
        private var mY: Float = 0.toFloat()

        override fun run() {
            val w = mX.div(boxWidth).toInt()
            val h = mY.div(boxHeight).toInt()
            val clickDay = (h) * 7 + w + 1 - week
            if (clickDay in 1..days) {
                if (nowYear == year) {
                    if (nowMonth < month) {
                        Utils.showToast("时间还没有到哦～")
                        return
                    }
                }

//                    KLog.e("yxs", "点击的：X:$w  Y:$h  日期：$clickDay")
                val bean = getNowDayData(clickDay)
                onPixelClickListener?.OnClick(
                    year,
                    month,
                    clickDay,
                    bean.int,
                    bean.boolean,
                    bean.str
                )
            }
        }

        fun setXY(x: Float, y: Float) {
            mX = x
            mY = y
        }
    }
}
